#include <cstdlib>
#include <iostream>
#include <unordered_map>
#include <vector>
#include "io/init.hpp"
#include "house/empty.hpp"
#include "house/mine.hpp"
#include "house/hospital.hpp"
#include "house/tool.hpp"
#include "house/reward.hpp"
#include "house/magic.hpp"
#include "house/begin.hpp"
#include "house/jail.hpp"
#include "house/reward.hpp"
#include "house/park.hpp"
#include "io/cmd.hpp"
#include "io/map_out.hpp"
#include "utils/macro.hpp"
#include <stdint.h>

//TODO
//read it from config
void InitUser(std::unordered_map<int, User*>& hashMap,int money,std::vector<int>& turn){
	for (auto num : turn) {
		switch (num) {
		case 1:
			hashMap[1]=new User(1,"钱夫人",money,'Q',Red);
			break;
		case 2:
			hashMap[2]=new User(2,"阿土伯",money,'A',Green);
			break;
		case 3:
			hashMap[3]=new User(3,"孙小美",money,'S',Blue);
			break;
		case 4:
			hashMap[4]=new User(4,"金贝贝",money,'J',Yellow);
			break;
		}
	}
}

void GameStart(){
	//获得玩家数量和初始资金
	auto turn=OptionUser();
	auto money=OptionMoney();
	const int mapSize=2*MAP_LINE+2*MAP_ROW-4;
	//绘制初始化地图
	std::vector<Land> map;
	for (int i=0; i<mapSize; i++) {
		if (i>=mapSize-6) {
			map.push_back(Land(new class Mine(i)));
		}else if(i==JAIL_POS||i==HOSPITAL_POS){
			map.push_back(Land(new class Park));
		}else if(i==HOSPITAL_POS){
			map.push_back(Land(new class Hospital));
		}else if(i==JAIL_POS){
			map.push_back(Land(new class Jail));
		}else if(i==BEGIN_POS){
			map.push_back(Land(new class Begin));
		}else if(i==TOOL_POS){
			map.push_back(Land(new class Tools));
		}else if(i==GIFT_POS){
			map.push_back(Land(new class Reward));
		}else if(i==MAGIC_POS){
			map.push_back(Land(new class Magic));
		}else{
			map.push_back(Land(new class Empty(i)));
		}
	}
	std::unordered_map<int, User*> users;
	CmdCtrl cmd;
	InitUser(users,money,turn);
	for (auto now : turn) {
		map[0].ChangeStatus(*users[now]);
	}
	MapDisplay(map);
	bool isEnd=false;
	int live=0,winner=0;
	while (1) {
		for (auto now : turn) {
			cmd.WaitInput(*users[now], map,users,turn);
			live=0;
			for (auto iter : users) {
				//TODO
				ASSERT(iter.second!=NULL);
				if (iter.second->GetStatus()!=Bankruptcy) {
					live++;
					winner=iter.second->GetId();
				}
			}
			if (live==1&&winner!=0) {
				isEnd=true;
				break;
			}
		}
		if (isEnd) {
			break;
		}
	}
	MapGameEnd(*users[winner]);
}

int main()
{
	GameStart();
	return 0;
}
